package com.trkj.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.trkj.dao.EmpDAO;
import com.trkj.dao.EmployDAO;
import com.trkj.dao.LeaveDAO;
import com.trkj.dao.LoanDAO;
import com.trkj.dao.NoticeDAO;
import com.trkj.dao.OverworkDAO;
import com.trkj.dao.QuitDAO;
import com.trkj.dao.ReloanDAO;
import com.trkj.dao.StandardDAO;
import com.trkj.dao.TransferDAO;
import com.trkj.pojo.Emp;
import com.trkj.pojo.Employ;
import com.trkj.pojo.Loan;
import com.trkj.pojo.Overwork;
import com.trkj.pojo.Quit;
import com.trkj.pojo.Standard;
import com.trkj.utils.PojoToVo;
import com.trkj.vo.BackLogProcessVo;

@Service
@Transactional
public class BackLogProcessService {
	@Autowired
	RepositoryService repositoryService;
	@Autowired
	HistoryService historyService;
	@Autowired
	RuntimeService runtimeService;
	@Autowired
	TaskService taskService;
	@Autowired
	WorkFlowService workFlowService;
	@Autowired
	EmpDAO empDAO;
	// 人员录用流程-------录用申请单
	@Autowired
	EmployDAO employDAO;
	// 人员转正流程-------转正申请单
	@Autowired
	StandardDAO standardDAO;
	// 人员借款流程-------借款申请单
	@Autowired
	LoanDAO loanDAO;
	// 人员请假流程-------请假申请单
	@Autowired
	LeaveDAO leaveDAO;
	// 人员调动流程-------调动申请单
	@Autowired
	TransferDAO transferDAO;
	// 人员还款流程-------还款申请单
	@Autowired
	ReloanDAO reloanDAO;
	// 人员加班流程-------加班申请单
	@Autowired
	OverworkDAO overworkDAO;
	// 人员离职流程-------离职申请单
	@Autowired
	QuitDAO quitDAO;
	// 通知发布流程-------通知申请单
	@Autowired
	NoticeDAO noticeDAO;
	@Autowired
	QuitService quitService;
	/**
	 * 查询流程
	 * @author Lixd
	 * @param processId 流程编号
	 * @param processName 规定流程类别
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T findProcess(Integer processId, String processName) {
		if (processId != null && processId != 0 && processName != null && processName.length() > 0) {
			if (processName.equals("人员录用流程")) {
				Employ employ = employDAO.findOne(processId);
				return (T) PojoToVo.EmployToEmployVo(employ);
			}else if (processName.equals("人员转正流程")) {
				Standard standard = standardDAO.findOne(processId);
				return (T) PojoToVo.StandardToStandardVo(standard);
			} else if (processName.equals("人员借款流程")) {
				Loan loan = loanDAO.findOne(processId);
				return (T) PojoToVo.LoanToLoanVo(loan);
			} else if (processName.equals("人员请假流程")) {
				return (T) leaveDAO.findOne(processId);
			} else if (processName.equals("人员调动流程")) {
				return (T) transferDAO.findOne(processId);
			} else if (processName.equals("人员还款流程")) {
				return (T) reloanDAO.findOne(processId);
			} else if (processName.equals("人员加班流程")) {
				Overwork overwork = overworkDAO.findOne(processId);
				return (T) PojoToVo.OverworkToOverWorkVo(overwork);
			} else if (processName.equals("人员离职流程")) {
				Quit quit = quitDAO.findOne(processId);
				return (T) PojoToVo.QuitToQuitVo(quit);
			} else if (processName.equals("通知发布流程")) {
				return (T) noticeDAO.findOne(processId);
			}
		}
		return null;
	}
	/**
	 * 将拿到的集合进行动态条件过滤
	 * 
	 * @author Lixd
	 * @param processID
	 *            过滤条件：流程编号
	 * @param processType
	 *            过滤条件：流程类型
	 * @param name
	 *            过滤条件：流程发起人
	 * @param page
	 *            条件：当前页
	 * @param rows
	 *            条件：页大小
	 * @param tasks
	 *            要过滤的集合对象
	 * @return List<BackLogProcessVo> 条件过滤后的集合
	 */
	public List<BackLogProcessVo> findMyPersonalTask(String processID, String processType, String name,
			List<Task> tasks) {
		// 新建一个集合，用于存放vo对象
		List<BackLogProcessVo> list = new ArrayList<>();
		for (Task task : tasks) {
			BackLogProcessVo bpv = new BackLogProcessVo();
			// 查询流程变量的processid的属性值
			bpv.setProcessId(String.valueOf(runtimeService.getVariable(task.getProcessInstanceId(), "processid")));
			// 通过任务（task）获取的流程定义id（ProcessDefinitionId）查询一个流程定义对象（processDefinition）
			ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
					.processDefinitionId(task.getProcessDefinitionId()).singleResult();
			// 通过流程定义对象（processDefinition）查询部署对象
			Deployment deployment = repositoryService.createDeploymentQuery()
					.processDefinitionKey(processDefinition.getKey())
					.orderByDeploymenTime().desc().list().get(0);
			// 通过部署对象设置vo的流程类型
			bpv.setProcessName(deployment.getName());
			// 通过任务获取的流程实例编号和usertask1查询一个历史任务实例，用于获取流程发起人的id
			HistoricTaskInstance histask = historyService.createHistoricTaskInstanceQuery()
					.processInstanceId(task.getProcessInstanceId()).taskDefinitionKey("usertask1").singleResult();
			// 获得流程发起人
			Emp luncher = empDAO.findOne(Integer.valueOf(histask.getAssignee()));
			// 设置流程发起人
			bpv.setLaunchPeople(luncher.getEmpName());
			// 格式化时间对象
			SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM-dd");
			// 流程发起时间
			bpv.setLaunchTime(sm.format(histask.getStartTime()));
			// 任务名称
			bpv.setTaskName(task.getName());
			// 任务开始时间
			bpv.setStartTime(sm.format(task.getCreateTime()));
			// 任务编号
			bpv.setTaskId(task.getId());
			// 所有条件不为空
			if (processID != null && processID.length() > 0 && processType != null && processType.length() > 0
					&& name != null && name.length() > 0) {
				if (bpv.getProcessId().indexOf(processID) >= 0 && bpv.getProcessName().indexOf(processType) >= 0
						&& bpv.getLaunchPeople().indexOf(name) >= 0) {
					list.add(bpv);
				}
				// processID 和 processType 不为空
			} else if (processID != null && processID.length() > 0 && processType != null && processType.length() > 0) {
				if (bpv.getProcessId().indexOf(processID) >= 0 && bpv.getProcessName().indexOf(processType) >= 0) {
					list.add(bpv);
				}
				// processID 和 name 不为空
			} else if (processID != null && processID.length() > 0 && name != null && name.length() > 0) {
				if (bpv.getProcessId().indexOf(processID) >= 0 && bpv.getLaunchPeople().indexOf(name) >= 0) {
					list.add(bpv);
				}
				// processType 和 name 不为空
			} else if (processType != null && processType.length() > 0 && name != null && name.length() > 0) {
				if (bpv.getProcessName().indexOf(processType) >= 0 && bpv.getLaunchPeople().indexOf(name) >= 0) {
					list.add(bpv);
				}
				// processType 不为空
			} else if (processType != null && processType.length() > 0) {
				if (bpv.getProcessName().indexOf(processType) >= 0) {
					list.add(bpv);
				}
				// processID 不为空
			} else if (processID != null && processID.length() > 0) {
				if (bpv.getProcessId().indexOf(processID) >= 0) {
					list.add(bpv);
				}
				// name 不为空
			} else if (name != null && name.length() > 0) {
				if (bpv.getLaunchPeople().indexOf(name) >= 0) {
					list.add(bpv);
				}
			} else {
				list.add(bpv);
			}
		}
		return list;
	}

	/**
	 * 封装datagrid要的map对象到jsp页面
	 * 
	 * @author Lixd
	 * @param useid
	 *            用户id，用于查询该用户的数据
	 * @param processID
	 *            条件：流程编号
	 * @param processType
	 *            条件：流程类型
	 * @param name
	 *            条件：流程发起人
	 * @param page
	 *            条件：当前页
	 * @param rows
	 *            条件：页大小
	 * @return Map<String, Object> datagrid要的map对象，封装了总记录数和当前页的数据
	 */
	public Map<String, Object> getPageBackLog(Integer useid, String processID, String processType, String name,
			Integer page, Integer rows) {
		Map<String, Object> map = new HashMap<>();
		if (page != null && page > 0 && rows != null && rows > 0) {
			// 查询没分页的所有集合
			List<Task> tasks = workFlowService.findMyPersonalTask(useid);
			// 没分页经过条件过滤的集合，用于获取总记录数
			List<BackLogProcessVo> list = findMyPersonalTask(processID, processType, name, tasks);
			//集合排序
			Collections.sort(list);
			// 分页后的集合
			List<BackLogProcessVo> list2 = new ArrayList<>();
			int i = (page - 1) * rows;// 起始下标
			int a = (page - 1) * rows;// 游动下标
			while (a - i < rows) {// 控制循环次数，固定为rows次
				if (a <= list.size() - 1) {// 防止最后一页时数组越界
					list2.add(list.get(a));// 在集合中加入当前页的数据
					a++;// 游动下标自加
				} else {
					break;// 最后一页，下标将越界时，退出循环
				}
			}
			map.put("total", list.size());
			map.put("rows", list2);
		}
		return map;
	}
}
